package com.leyou.item.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.common.constants.MQConstants;
import com.leyou.common.exception.pojo.ExceptionEnum;
import com.leyou.common.exception.pojo.LyException;
import com.leyou.common.pojo.PageResult;
import com.leyou.common.utils.BeanHelper;
import com.leyou.item.mapper.SkuMapper;
import com.leyou.item.mapper.SpuDetailMapper;
import com.leyou.item.mapper.SpuMapper;
import com.ly.plus.dto.SpuDTO;
import com.ly.plus.entity.Category;
import com.ly.plus.entity.Sku;
import com.ly.plus.entity.Spu;
import com.ly.plus.entity.SpuDetail;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 * User: ycs
 * Date: 2020/8/20
 * Time: 20:01
 * Description: No Description
 */
@Service
@Transactional
public class GoodsService extends ServiceImpl<SkuMapper,Sku> {
    @Autowired(required = false)
    private SpuMapper spuMapper;
    @Autowired(required = false)
    private SpuDetailMapper spuDetailMapper;
    @Autowired(required = false)
    private SkuMapper skuMapper;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private BrandService brandService;
    @Autowired
    private AmqpTemplate amqpTemplate;
    /**
     * 分页查询商品
     * @param key 搜索关键字
     * @param saleable //是否根据上下架查询
     * @param page //当前页
     * @param rows //一页展示总数
     * @return
     */
    public PageResult<SpuDTO> findGoodsByPage(String key, Boolean saleable, Long page, Long rows) {
        //封装分页条件
        IPage<Spu> iPage=new Page<>(page,rows);
        //封装查询条件
        QueryWrapper<Spu> wrapper = Wrappers.query();
        if (StringUtils.isNotEmpty(key)){
            //搜索条件
            wrapper.like("name",key);
        }
        if (saleable!=null){
            //是否上下架
            wrapper.eq("saleable",saleable);
        }

        iPage=spuMapper.selectPage(iPage,wrapper);
        List<Spu> spus = iPage.getRecords();
        if (CollectionUtils.isEmpty(spus)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        //数据复制
        List<SpuDTO> spuDTOS = BeanHelper.copyWithCollection(spus, SpuDTO.class);
        //给每一个商品的分类与品牌名称赋值
        handlerBrandNameAndCategoryName(spuDTOS);
        return new PageResult<>(iPage.getTotal(), iPage.getPages(), spuDTOS);
    }
    //给每一个商品的分类与品牌名称赋值方法
    private void handlerBrandNameAndCategoryName(List<SpuDTO> spuDTOS) {
        spuDTOS.forEach(spu->{
            //设置品牌名
            String name = brandService.findBrandById(spu.getBrandId()).getName();
            spu.setBrandName(name);
            //获取分类集
            List<Category> categoryList = categoryService.findCategorysByIds(spu.getCategoryIds());
            //转化成流拼接分类名称
            String CategoryNames = categoryList.stream().map(Category::getName).collect(Collectors.joining("|"));
            //设置名称
            spu.setCategoryName(CategoryNames);
        });
    }
    /**
     * 添加spu
     * @param spuDTO//封装对象
     *      入口:http://api.leyou.com/api/item/goods
     * @return
     */
    public void saveSpu(SpuDTO spuDTO) {
        try {
            //拷贝数据
            Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
            //默认不上架
            spu.setSaleable(false);
            spuMapper.insert(spu);
            SpuDetail spuDetail = spuDTO.getSpuDetail();
            //一对一表设置id
            spuDetail.setSpuId(spu.getId());
            List<Sku> skus = spuDTO.getSkus();
            spuDetailMapper.insert(spuDetail);
            skus.forEach(sku -> {
                sku.setSpuId(spu.getId());
                //skuMapper.insert(sku);//效率太低
            });
            super.saveBatch(skus);
        } catch (Exception e) {
            e.printStackTrace();
            throw new LyException(ExceptionEnum.FILE_WRITER_ERROR);
        }

    }
    /**
     * 根据id修改上下架信息
     * @param id
     * @param saleable
     * @return
     */
    public void updateSaleable(Long id, Boolean saleable) {
        try {
            //封装修改信息
            Spu spu = new Spu();
            spu.setSaleable(saleable);
            spu.setId(id);
            //修改信息
            spuMapper.updateById(spu);
            //判断路由key
            String key=saleable?MQConstants.RoutingKey.ITEM_UP_KEY:MQConstants.RoutingKey.ITEM_DOWN_KEY;
            //发送消息到对列
            amqpTemplate.convertAndSend(MQConstants.Exchange.ITEM_EXCHANGE_NAME,key,id);
        } catch (Exception e) {
            e.printStackTrace();
            throw  new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }

    }
    /**
     * 根据spuid获取sku集合
     * @param id
     * @return
     */
    public List<Sku> findSkuBySpuId(Long id) {
        Sku sku=new Sku();
        sku.setSpuId(id);
        QueryWrapper<Sku> warpper = Wrappers.query(sku);
        List<Sku> skuList = skuMapper.selectList(warpper);
        if (CollectionUtils.isEmpty(skuList)){
            throw  new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return skuList;
    }
    /**
     * 根据spuid获取SpuDetail
     * @param id
     * @return
     */
    public SpuDetail findSpuDetailById(Long id) {
        SpuDetail spuDetail = spuDetailMapper.selectById(id);
        if (spuDetail==null){
            throw  new  LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return spuDetail;
    }
    /**
     * 根据id获取spu
     * @param id
     * @return
     */
    public SpuDTO findSpuById(Long id) {
        Spu spu = spuMapper.selectById(id);
        SpuDTO spuDTO = BeanHelper.copyProperties(spu, SpuDTO.class);
        return spuDTO;
    }
}
